<!-- 全局公共搜索表单组件 -->
<template>
  <ele-card :body-style="{ paddingBottom: '2px' }">
    <div class="fixed-button-container">
      <el-button
        type="text"
        @click="showConfig = !showConfig"
        class="custom-search-btn"
      >
        <ElIcon v-if="showConfig" class="icon"><ArrowUp /></ElIcon>
        <ElIcon v-else class="icon"><ArrowDown /></ElIcon>
        <span class="btn-text">搜索项</span>
      </el-button>
    </div>
    <el-drawer v-model="showConfig" title="搜索项配置" size="30%">
      <div class="config-container">
        <div
          style="
            margin-bottom: 16px;
            display: flex;
            justify-content: space-between;
            align-items: center;
          "
        >
          <el-checkbox
            v-model="isCheckAll"
            :indeterminate="isIndeterminate"
            @change="handleCheckAllChange"
          >
            全选
          </el-checkbox>
          <el-button type="text" @click="resetSearchItems">重置</el-button>
        </div>
        <draggable
          v-model="localSearchItems"
          item-key="prop"
          class="drag-container"
          :animation="300"
          :force-fallback="true"
          fallback-class="dragging-active"
          ghost-class="ghost-hidden"
          handle=".drag-handle"
        >
          <template #item="{ element }">
            <div class="drag-item">
              <div class="drag-item-content">
                <div class="drag-handle" @click.stop>
                  <ElIcon>
                    <HolderOutlined />
                  </ElIcon>
                </div>
                <el-checkbox v-model="element.visible" style="flex: 1">{{
                  element.label
                }}</el-checkbox>
              </div>
            </div>
          </template>
        </draggable>
      </div>
    </el-drawer>
    <el-form
      label-width="72px"
      @keyup.enter="handleSearch"
      @submit.prevent="handleSearch"
    >
      <el-row :gutter="8">
        <el-col
          v-for="item in filteredItems"
          :key="item.prop"
          v-bind="item.span"
        >
          <el-form-item
            :label="item.label"
            :label-width="item.labelWidth || '72px'"
          >
            <component
              :is="item.component"
              v-model="form[item.prop]"
              v-bind="item.props"
              class="ele-fluid"
            />
          </el-form-item>
        </el-col>
        <SearchButtons>
          <el-button type="primary" @click="handleSearch">查询</el-button>
          <el-button @click="reset">重置</el-button>
        </SearchButtons>
      </el-row>
    </el-form>
  </ele-card>
</template>

<script setup>
import { ref, computed, watch, onMounted } from "vue";
import { cloneDeep, isEqual } from "lodash";
import { useFormData } from "@/utils/use-form-data";
import draggable from "vuedraggable";
import { ElCheckbox } from "element-plus";
import { HolderOutlined } from "@/components/icons";
import { ArrowUp, ArrowDown } from "@element-plus/icons-vue";

// 搜索项默认配置
const defaultSearchItem = {
  component: "el-input",
  visible: true,
  span: { lg: 6, md: 8, sm: 12, xs: 24 },
};

const props = defineProps({
  cacheKey: {
    type: String,
    default: "",
  },
  searchItems: {
    type: Array,
    required: true,
    description: "搜索项配置数组",
  },
  formConfig: {
    type: Object,
    default: () => ({}),
    description: "表单初始配置",
  },
});
// 本地状态管理prop，解决v-model不能直接绑定prop的问题
const emit = defineEmits(["search", "update:searchItems"]);

const searchCacheKey = computed(() => {
  return props.cacheKey ? `${props.cacheKey}Search` : "";
});

// 从缓存加载搜索项状态
const loadSearchItemsFromCache = () => {
  if (searchCacheKey.value) {
    const cached = localStorage.getItem(searchCacheKey.value);
    if (cached) {
      return JSON.parse(cached);
    }
  }
  return null;
};

// 保存搜索项状态到缓存
const saveSearchItemsToCache = () => {
  console.log(localSearchItems.value);
  if (searchCacheKey.value) {
    localStorage.setItem(
      searchCacheKey.value,
      JSON.stringify(localSearchItems.value),
    );
  }
};

// 初始化本地搜索项
const initLocalSearchItems = () => {
  const cachedItems = loadSearchItemsFromCache();
  if (cachedItems) {
    console.log("Loaded from cache:", cachedItems);
    return cachedItems;
  }
  // 默认全部选中
  return props.searchItems.map((item) => ({
    ...defaultSearchItem,
    ...item,
    visible: item.visible ?? defaultSearchItem.visible,
  }));
};

// 本地状态管理prop，解决v-model不能直接绑定prop的问题
const localSearchItems = ref(initLocalSearchItems());
const isComponentInitialized = ref(false);

// 组件初始化完成后设置标志
onMounted(() => {
  isComponentInitialized.value = true;
  console.log("Component initialized, cache status:", localSearchItems.value);
});

// 监听搜索项变化，保存到缓存
watch(
  localSearchItems,
  () => {
    saveSearchItemsToCache();
  },
  { deep: true },
);

// 全选相关状态
const isCheckAll = ref(false);
const isIndeterminate = ref(false);

// 监听搜索项变化，更新全选状态
watch(
  () => localSearchItems.value,
  (newVal) => {
    if (!newVal.length) {
      isCheckAll.value = false;
      isIndeterminate.value = false;
      return;
    }
    const checkedCount = newVal.filter((item) => item.visible).length;
    isCheckAll.value = checkedCount === newVal.length;
    isIndeterminate.value = checkedCount > 0 && checkedCount < newVal.length;
  },
  { deep: true, immediate: true },
);

// 全选/取消全选处理
const handleCheckAllChange = (checked) => {
  localSearchItems.value = localSearchItems.value.map((item) => ({
    ...item,
    visible: checked,
  }));
  isIndeterminate.value = false;
  emit("update:searchItems", [...localSearchItems.value]);
};

// 监听prop变化并更新本地状态
watch(
  () => props.searchItems,
  (newVal) => {
    // 组件初始化完成后才响应prop变化
    if (
      isComponentInitialized.value &&
      !isEqual(newVal, localSearchItems.value)
    ) {
      localSearchItems.value = newVal.map((item) => ({
        ...defaultSearchItem,
        ...item,
        visible: item.visible ?? defaultSearchItem.visible,
      }));
    }
  },
  // 移除immediate选项，避免初始加载时触发
);

// 当本地状态变化时通知父组件更新
watch(
  localSearchItems,
  (newVal) => {
    emit("update:searchItems", newVal);
  },
  { deep: true },
);

// 显示配置面板
const showConfig = ref(false);

// 过滤可见的搜索项
const filteredItems = computed(() => {
  return localSearchItems.value.filter((item) => item.visible);
});

const [form, resetFields] = useFormData(
  cloneDeep(props.formConfig),
  searchCacheKey.value,
);

/** 搜索 */
const handleSearch = () => {
  emit("search", { ...form });
};

/** 重置 */
const reset = () => {
  resetFields();
  handleSearch();
};

// 重置搜索项为默认全部选中
const resetSearchItems = () => {
  localSearchItems.value = props.searchItems.map((item) => ({
    ...defaultSearchItem,
    ...item,
    visible: true,
  }));
  isCheckAll.value = true;
  isIndeterminate.value = false;
  saveSearchItemsToCache();
  emit("update:searchItems", [...localSearchItems.value]);
};
</script>

<style scoped>
.drag-container {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  padding: 10px;
}
.drag-item {
  width: calc(50% - 15px);
  margin-bottom: 0 !important;
  box-sizing: border-box;
}
.drag-item-content {
  display: flex;
  align-items: center;
  padding: 8px;
  border: 1px solid #e5e7eb;
  border-radius: 4px;
}
.drag-item-content {
  display: flex;
  align-items: center;
  /* width: 100%; */
}
.drag-handle {
  margin-right: 5px;
}
.drag-handle {
  cursor: move;
  padding: 0 8px;
}
.drag-handle:hover {
  cursor: move;
}
.dragging-active {
  position: fixed;
  z-index: 9999;
  opacity: 0.95;
  background: white;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.ghost-hidden {
  opacity: 0;
}
.fixed-button-container {
  position: fixed;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  background: #fff;
  box-shadow: -2px 0 5px rgba(0, 0, 0, 0.1);
  transition: width 0.3s ease;
  width: 40px;
  overflow: hidden;
  z-index: 1000;
}
.fixed-button-container:hover {
  width: auto;
}
.custom-search-btn {
  display: flex;
  align-items: center;
  padding: 8px 12px;
}
.btn-text {
  margin-left: 8px;
  white-space: nowrap;
}
.icon {
  font-size: 16px;
  color: #606266;
}
</style>
